import { ImageDisplayNode, ImageImportNode } from "./ImageBasic";
import {
  ImageSharpenNode,
  ImageLinearEnhancement,
  ImageNonLinearEnhancement,
  ImageEqualizeHist,
} from "./ImageEnhancement";
import { ImageMergeNode, ImageHumanSegNode } from "./ImageMergeSeg";
import {
  ImageGrayScaleNode,
  ImageFFTNode,
  ImageDCTNode,
  ImageHistgramNode,
} from "./ImageTransform";

import { ImageProjectionNode, ImageDeBlurNode } from "./ImageRestoration";

import axios from "axios";

const nodeTypes = {
  imageImport: ImageImportNode,
  imageDisplay: ImageDisplayNode,

  imageMerge: ImageMergeNode,
  imageHumanSeg: ImageHumanSegNode,

  imageGrayScale: ImageGrayScaleNode,
  imageFFT: ImageFFTNode,
  imageDCT: ImageDCTNode,
  imageHistgram: ImageHistgramNode,

  imageSharpen: ImageSharpenNode,
  imageLinearEnhancement: ImageLinearEnhancement,
  imageNonLinearEnhancement: ImageNonLinearEnhancement,
  imageEqualizeHist: ImageEqualizeHist,

  imageProjection: ImageProjectionNode,
  imageDeBlur: ImageDeBlurNode
};

function NodeBuilder(id, type, position = { x: 0, y: 0 }) {
  return {
    id: id,
    type: type,
    data: {
      options: {},
    },
    position: position,
  };
}

async function exportJson(nodes, edges) {
  let data = [];

  /**
   * 处理节点
   */
  let id_node_map = {};
  const nd_num = nodes.length;
  for (let i = 0; i < nd_num; i++) {
    const nd = nodes[i];
    id_node_map[nd.id] = i; //储存特定id的node在数组中的下标，便于后续查找添加邻接表

    data.push({
      id: nd.id, //id
      type: nd.type, //类型
      front: [], //前向节点
      next: [], //后向节点
      out_flow: [], //第i输出连接到第j个node的第k个输入
      options: nd.data.options, //用户输入的参数
    });
  }

  /**
   * 处理连接关系
   * s节点的第i个输出，对应着j节点的第k个输入
   */
  const edges_num = edges.length;
  for (let e = 0; e < edges_num; e++) {
    const ed = edges[e];
    //添加邻接节点信息
    const s = id_node_map[ed.source]; //源节点source
    const j = id_node_map[ed.target]; //目标节点j
    array_add_without_repetition(
      data[s].next, //next列表
      j //目标节点
    );
    array_add_without_repetition(
      data[j].front, //front列表
      s //源节点
    );

    //添加输入输出信息
    const i = Number(ed.sourceHandle); //第i个输出
    const k = Number(ed.targetHandle); //第k的输入

    if (data[s].out_flow[i] === undefined) {
      data[s].out_flow[i] = [];
    }
    data[s].out_flow[i].push([j, k]); //第i个输出，对于第j的节点的第k输入
  }

  // console.log(data);
  console.log(JSON.stringify(data));

  /**
   * 上传
   */

  /**通过http */
  try {
    const result = await axios.post("http://localhost:5056/exec", data);

    if (result.data["status"] === "runtime error") {
      throw "runtime error";
    }

    return result.data.result;
  } catch (e) {
    console.log(e);
    if (e === "runtime error") {
      throw "节点运行时出错";
    }
    throw "请求服务出错";
  }
}

function array_add_without_repetition(array, el) {
  const len = array.length;
  for (let i = 0; i < len; i++) {
    if (array[i] === el) {
      return;
    }
  }
  array.push(el);
}

export { NodeBuilder, nodeTypes, exportJson };
